import { Button, message } from 'antd'
import { FC, useContext, useEffect, useMemo, useState } from 'react'
import { cloneDeep } from 'lodash'
import ShuDuItem from '../ShuDuItem'
import QuestionList from '../../assets/questionList.json'
import {
  fillPossibilityNumber,
  findNumberAllProcess,
  judgeShuDuError
} from '../../logic/handleData'
import { QUESTION_LIST, getLSData, setQuestion } from '../../logic/handleLS'
import { isValidArray } from '../../logic/utils'
import QuestionSelector from '../QuestionSelector'
import { DataContext } from '../../logic/DataContext'

import './index.scss'
import { adminUsername } from '../../constants'
import { request } from '../../logic/request'

interface Props {
  onFinish(item: ShuDuNS.ResultItemStr): void
}

// 整个数独
const ShuDu: FC<Props> = (props) => {
  const { onFinish } = props
  const [data, setData] = useState<ShuDuNS.ShuDuData>([])
  const [questionIndex, setQuestionIndex] = useState('')
  const [questionLevel, setQuestionLevel] = useState(1)
  const [duration, setDuration] = useState(0)
  const [isFinished, setIsFinished] = useState(false)
  const { username } = useContext(DataContext)
  const isMain = useMemo(() => username === adminUsername, [username])
  // 格式化之后的时长
  const formattedDuration = useMemo(() => {
    if (!duration) return 0
    // 把秒转换成形式： 分-秒
    const minute = Math.floor(duration / 60)
    const second = duration % 60
    return `${minute}分 ${second}秒`
  }, [duration])

  // #region 找数字法
  /**
   * 通过 xy 设置值
   */
  function setDataByXY(x: number, y: number, value: number) {
    setData((old) => {
      const clone = [...old]
      clone[x][y].value = value
      return clone
    })
  }

  /**
   * 找数字法
   */
  function handleFillByNumber() {
    findNumberAllProcess(data, setDataByXY)
  }

  // 补全法
  function handleFillAll() {
    fillPossibilityNumber(data, setDataByXY)
  }
  // #endregion

  // 改变题目
  function handleQuestionChange(question: ShuDuNS.QuestionItem) {
    // 改变题目时，先去 LS 中找一下有没有历史记录
    const questionList: ShuDuNS.QuestionItem[] = getLSData(QUESTION_LIST) || []
    const rightQuestion = questionList.find((item) => item.id === question.id)
    // 在变更题目之前，先把当前题目存进去
    setQuestion(questionIndex, {
      id: questionIndex,
      level: questionLevel,
      duration,
      value: data,
      isFinished
    })
    // 如果有历史记录，则使用历史记录
    if (rightQuestion) {
      setData(rightQuestion.value)
      setQuestionIndex(rightQuestion.id)
      setQuestionLevel(rightQuestion.level)
      setDuration(rightQuestion.duration ?? 0)
      setIsFinished(rightQuestion.isFinished ?? false)
    } else {
      // 如果没有，使用默认
      setData(question.value)
      setQuestionIndex(question.id)
      setQuestionLevel(question.level)
      setDuration(0)
      setIsFinished(false)
    }
  }

  // 验证题目是否完成，然后进行下一步
  function validateQuestion() {
    // 如果错误，直接提示，看看要不要指出来哪里有问题
    if (!judgeShuDuError(data)) {
      message.error('有问题啊，先检查一下吧')
      return
    }
    setQuestion(questionIndex, {
      id: questionIndex,
      level: questionLevel,
      duration,
      value: data,
      isFinished: true
    })
    // 验证通过，调用函数，调用接口
    onFinish({
      id: questionIndex,
      level: questionLevel,
      duration
    })
    request({
      url: '/finishQuestion',
      method: 'post',
      data: {
        username,
        level: questionLevel,
        id: questionIndex
      }
    })
      .then((res: any) => {
        if (res) {
          message.success('验证成功！')
          setIsFinished(true)
        } else {
          message.error(res.message || '你有问题')
        }
      })
      .catch(() => {})
  }

  useEffect(() => {
    let questionIndexL
    let questionLevelL
    let dataL
    // 先判断 LS 中有没有上次剩下的数据，再去使用第一题
    const questionRecord: ShuDuNS.QuestionItem[] = getLSData(QUESTION_LIST)
    if (isValidArray(questionRecord)) {
      const {
        value,
        id,
        level,
        duration: durationL = 0,
        isFinished: isFinishedL = false
      } = questionRecord[0]
      questionIndexL = id
      questionLevelL = level
      dataL = value
      setDuration(durationL)
      setIsFinished(isFinishedL)
    } else {
      questionIndexL = QuestionList[0].id
      questionLevelL = QuestionList[0].level
      dataL = cloneDeep(QuestionList[0].value)
    }
    setQuestionIndex(questionIndexL)
    setQuestionLevel(questionLevelL)
    setData(dataL)
  }, [])

  useEffect(() => {
    function changeDuration() {
      if (isFinished) return
      setDuration((old) => old + 1)
    }
    const timer = window.setInterval(changeDuration, 1000)
    return () => {
      window.clearInterval(timer)
    }
  }, [isFinished])

  return (
    <div className="shuDu">
      {isMain && (
        <div className="operators">
          操作栏：
          <div className="funcContainer">
            <Button onClick={handleFillByNumber}>找数字法</Button>
          </div>
          &nbsp;
          <Button onClick={handleFillAll}>补全法</Button>&nbsp;
        </div>
      )}

      <div className="message">
        题目：{questionIndex}&nbsp;难度：{questionLevel}
        &nbsp;<div className="duration">用时：{formattedDuration}</div>
        {!isFinished && (
          <>
            &nbsp;
            <Button type="primary" onClick={validateQuestion} size="small">
              提交
            </Button>
          </>
        )}
      </div>
      <ShuDuItem data={data} />
      <QuestionSelector onQuestionChange={handleQuestionChange} />
    </div>
  )
}

export default ShuDu
